﻿using HalconDotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Hanbo.CalibrationModule
{
	public class QualityProcedures
	{
		/// <summary>
		/// Evaluates the sharpness of the calibration plate in the calibration
		/// image.
		/// </summary>
		public void eval_caltab_focus(HObject ho_Image,
									   HObject ho_Marks,
									   HTuple hv_Contrast,
									   out HTuple hv_FocusScore)
		{
			// Local iconic variables 

			HObject ho_Region, ho_RegionUnion, ho_ImageReduced;
			HObject ho_DerivGauss;

			// Local control variables 

			HTuple hv_Number, hv_MeanGradient, hv_Deviation;
			HTuple hv_MinScore, hv_RawResult;

			// Initialize local and output iconic variables 
			HOperatorSet.GenEmptyObj(out ho_Region);
			HOperatorSet.GenEmptyObj(out ho_RegionUnion);
			HOperatorSet.GenEmptyObj(out ho_ImageReduced);
			HOperatorSet.GenEmptyObj(out ho_DerivGauss);

			hv_FocusScore = 0.0;
			if ((int)(new HTuple(hv_Contrast.TupleEqual(0))) != 0)
			{
				ho_Region.Dispose();
				ho_RegionUnion.Dispose();
				ho_ImageReduced.Dispose();
				ho_DerivGauss.Dispose();

				return;
			}
			HOperatorSet.CountObj(ho_Marks, out hv_Number);
			if ((int)(new HTuple(hv_Number.TupleLess(3))) != 0)
			{
				ho_Region.Dispose();
				ho_RegionUnion.Dispose();
				ho_ImageReduced.Dispose();
				ho_DerivGauss.Dispose();

				return;
			}
			ho_Region.Dispose();
			HOperatorSet.GenRegionContourXld(ho_Marks, out ho_Region, "margin");
			ho_RegionUnion.Dispose();
			HOperatorSet.Union1(ho_Region, out ho_RegionUnion);
			ho_ImageReduced.Dispose();
			HOperatorSet.ReduceDomain(ho_Image, ho_RegionUnion, out ho_ImageReduced);
			ho_DerivGauss.Dispose();
			HOperatorSet.DerivateGauss(ho_ImageReduced, out ho_DerivGauss, 0.7, "gradient");
			HOperatorSet.Intensity(ho_Region, ho_DerivGauss, out hv_MeanGradient, out hv_Deviation);
			hv_MinScore = 0.25;
			//Normalize the Gradient with the contrast
			hv_RawResult = hv_MeanGradient / hv_Contrast;
			hv_FocusScore = (((hv_RawResult * 4.5)).TupleSort())[(new HTuple((new HTuple(hv_RawResult.TupleLength()
				)) / 20.0)).TupleRound()];
			hv_FocusScore = ((((((((hv_FocusScore - hv_MinScore)).TupleConcat(0.0))).TupleMax()
				)).TupleConcat(1.0))).TupleMin();
			ho_Region.Dispose();
			ho_RegionUnion.Dispose();
			ho_ImageReduced.Dispose();
			ho_DerivGauss.Dispose();

			return;
		}



		/// <summary>
		/// Extracts the calibration plate and the marks on this plate
		/// for the supplied image
		/// </summary>
		public void find_caltab_edges(HObject ho_Image,
									   out HObject ho_Caltab,
									   out HObject ho_Marks,
									   HTuple hv_DescriptionFileName)
		{

			// Stack for temporary objects 
			HObject[] OTemp = new HObject[20];
			long SP_O = 0;

			// Local iconic variables 

			HObject ho_ImageMean, ho_RegionDynThresh, ho_RegionBorder;
			HObject ho_RegionOpening1, ho_ConnectedRegions1, ho_SelectedRegions4;
			HObject ho_SelectedRegions5, ho_RegionBorder2, ho_RegionTrans;
			HObject ho_RegionErosion, ho_RegionBorder1, ho_RegionDilation2;
			HObject ho_RegionDifference1, ho_RegionOpening, ho_ConnectedRegions;
			HObject ho_SelectedRegions2, ho_SelectedRegions, ho_RegionFillUp;
			HObject ho_SelectedRegions1, ho_RegionIntersection, ho_RegionFillUp1;
			HObject ho_RegionDifference, ho_CaltabCandidates, ho_ObjectSelected = null;
			HObject ho_ConnectedMarks = null, ho_ObjectSelectedCaltab = null;
			HObject ho_RegionFillUpCand, ho_MarksCand, ho_RegionDilation1;
			HObject ho_ImageReduced, ho_DefaultEdges, ho_UnionContours;
			HObject ho_SelectedXLD, ho_SelectedXLD1;


			// Local control variables 

			HTuple hv_ExpDefaultCtrlDummyVar, hv_Width;
			HTuple hv_Height, hv_EstimatedCaltabSize, hv_EstimatedMarkSize;
			HTuple hv_Number, hv_X, hv_Y, hv_Z, hv_NumDescrMarks, hv_Index;
			HTuple hv_NumberMarks = new HTuple(), hv_Anisometry = new HTuple();
			HTuple hv_Bulkiness = new HTuple(), hv_StructureFactor = new HTuple();
			HTuple hv_AreaMarks = new HTuple(), hv_Row = new HTuple();
			HTuple hv_Column = new HTuple(), hv_Rectangularity, hv_SortedIndex;
			HTuple hv_IndexBest, hv_MinContrast, hv_NumberCand, hv_Area;
			HTuple hv_Dummy, hv_DummyS, hv_AreaMedian;

			// Initialize local and output iconic variables 
			HOperatorSet.GenEmptyObj(out ho_Caltab);
			HOperatorSet.GenEmptyObj(out ho_Marks);
			HOperatorSet.GenEmptyObj(out ho_ImageMean);
			HOperatorSet.GenEmptyObj(out ho_RegionDynThresh);
			HOperatorSet.GenEmptyObj(out ho_RegionBorder);
			HOperatorSet.GenEmptyObj(out ho_RegionOpening1);
			HOperatorSet.GenEmptyObj(out ho_ConnectedRegions1);
			HOperatorSet.GenEmptyObj(out ho_SelectedRegions4);
			HOperatorSet.GenEmptyObj(out ho_SelectedRegions5);
			HOperatorSet.GenEmptyObj(out ho_RegionBorder2);
			HOperatorSet.GenEmptyObj(out ho_RegionTrans);
			HOperatorSet.GenEmptyObj(out ho_RegionErosion);
			HOperatorSet.GenEmptyObj(out ho_RegionBorder1);
			HOperatorSet.GenEmptyObj(out ho_RegionDilation2);
			HOperatorSet.GenEmptyObj(out ho_RegionDifference1);
			HOperatorSet.GenEmptyObj(out ho_RegionOpening);
			HOperatorSet.GenEmptyObj(out ho_ConnectedRegions);
			HOperatorSet.GenEmptyObj(out ho_SelectedRegions2);
			HOperatorSet.GenEmptyObj(out ho_SelectedRegions);
			HOperatorSet.GenEmptyObj(out ho_RegionFillUp);
			HOperatorSet.GenEmptyObj(out ho_SelectedRegions1);
			HOperatorSet.GenEmptyObj(out ho_RegionIntersection);
			HOperatorSet.GenEmptyObj(out ho_RegionFillUp1);
			HOperatorSet.GenEmptyObj(out ho_RegionDifference);
			HOperatorSet.GenEmptyObj(out ho_CaltabCandidates);
			HOperatorSet.GenEmptyObj(out ho_ObjectSelected);
			HOperatorSet.GenEmptyObj(out ho_ConnectedMarks);
			HOperatorSet.GenEmptyObj(out ho_ObjectSelectedCaltab);
			HOperatorSet.GenEmptyObj(out ho_RegionFillUpCand);
			HOperatorSet.GenEmptyObj(out ho_MarksCand);
			HOperatorSet.GenEmptyObj(out ho_RegionDilation1);
			HOperatorSet.GenEmptyObj(out ho_ImageReduced);
			HOperatorSet.GenEmptyObj(out ho_DefaultEdges);
			HOperatorSet.GenEmptyObj(out ho_UnionContours);
			HOperatorSet.GenEmptyObj(out ho_SelectedXLD);
			HOperatorSet.GenEmptyObj(out ho_SelectedXLD1);

			//
			ho_Marks.Dispose();
			HOperatorSet.GenEmptyObj(out ho_Marks);
			ho_Caltab.Dispose();
			HOperatorSet.GenEmptyObj(out ho_Caltab);
			HOperatorSet.GetImagePointer1(ho_Image, out hv_ExpDefaultCtrlDummyVar, out hv_ExpDefaultCtrlDummyVar,
				out hv_Width, out hv_Height);
			hv_EstimatedCaltabSize = (((((hv_Width.TupleConcat(hv_Height))).TupleMax()) / 2.5)).TupleRound()
				;
			hv_EstimatedMarkSize = ((hv_EstimatedCaltabSize / 12.0)).TupleRound();
			ho_ImageMean.Dispose();
			HOperatorSet.MeanImage(ho_Image, out ho_ImageMean, hv_EstimatedMarkSize * 3, hv_EstimatedMarkSize * 3);
			ho_RegionDynThresh.Dispose();
			HOperatorSet.DynThreshold(ho_Image, ho_ImageMean, out ho_RegionDynThresh, 3,
				"light");
			ho_RegionBorder.Dispose();
			HOperatorSet.DynThreshold(ho_Image, ho_ImageMean, out ho_RegionBorder, 20, "dark");
			ho_RegionOpening1.Dispose();
			HOperatorSet.OpeningCircle(ho_RegionBorder, out ho_RegionOpening1, 1.5);
			ho_ConnectedRegions1.Dispose();
			HOperatorSet.Connection(ho_RegionOpening1, out ho_ConnectedRegions1);
			ho_SelectedRegions4.Dispose();
			HOperatorSet.SelectShape(ho_ConnectedRegions1, out ho_SelectedRegions4, "compactness",
				"and", 17, 50);
			ho_SelectedRegions5.Dispose();
			HOperatorSet.SelectShape(ho_SelectedRegions4, out ho_SelectedRegions5, "anisometry",
				"and", 1, 1.4);
			ho_RegionBorder2.Dispose();
			HOperatorSet.Boundary(ho_SelectedRegions5, out ho_RegionBorder2, "outer");
			ho_SelectedRegions5.Dispose();
			HOperatorSet.SelectShape(ho_RegionBorder2, out ho_SelectedRegions5, "circularity",
				"and", 0.006, 1);
			ho_RegionTrans.Dispose();
			HOperatorSet.ShapeTrans(ho_SelectedRegions5, out ho_RegionTrans, "rectangle2");
			ho_RegionErosion.Dispose();
			HOperatorSet.ErosionCircle(ho_RegionTrans, out ho_RegionErosion, (hv_Width / 640.0) * 5.5);
			ho_RegionBorder1.Dispose();
			HOperatorSet.Boundary(ho_RegionErosion, out ho_RegionBorder1, "inner");
			ho_RegionDilation2.Dispose();
			HOperatorSet.DilationCircle(ho_RegionBorder1, out ho_RegionDilation2, 3.5);
			ho_RegionDifference1.Dispose();
			HOperatorSet.Difference(ho_RegionDynThresh, ho_RegionDilation2, out ho_RegionDifference1
				);
			ho_RegionOpening.Dispose();
			HOperatorSet.OpeningCircle(ho_RegionDifference1, out ho_RegionOpening, (hv_Width / 640) * 1.5);
			ho_ConnectedRegions.Dispose();
			HOperatorSet.Connection(ho_RegionOpening, out ho_ConnectedRegions);
			ho_SelectedRegions2.Dispose();
			HOperatorSet.SelectShape(ho_ConnectedRegions, out ho_SelectedRegions2, "area",
				"and", (hv_EstimatedCaltabSize.TuplePow(2)) / 10, (hv_EstimatedCaltabSize.TuplePow(
				2)) * 5);
			ho_SelectedRegions.Dispose();
			HOperatorSet.SelectShape(ho_SelectedRegions2, out ho_SelectedRegions, "compactness",
				"and", 1.4, 10);
			ho_RegionFillUp.Dispose();
			HOperatorSet.FillUp(ho_SelectedRegions, out ho_RegionFillUp);
			ho_SelectedRegions1.Dispose();
			HOperatorSet.SelectShape(ho_RegionFillUp, out ho_SelectedRegions1, "rectangularity",
				"and", 0.6, 1);
			ho_RegionIntersection.Dispose();
			HOperatorSet.Intersection(ho_SelectedRegions1, ho_RegionDynThresh, out ho_RegionIntersection
				);
			ho_RegionFillUp1.Dispose();
			HOperatorSet.FillUp(ho_RegionIntersection, out ho_RegionFillUp1);
			ho_RegionDifference.Dispose();
			HOperatorSet.Difference(ho_RegionFillUp1, ho_RegionIntersection, out ho_RegionDifference
				);
			HOperatorSet.CountObj(ho_RegionDifference, out hv_Number);
			ho_CaltabCandidates.Dispose();
			HOperatorSet.GenEmptyObj(out ho_CaltabCandidates);
			HOperatorSet.CaltabPoints(hv_DescriptionFileName, out hv_X, out hv_Y, out hv_Z);
			hv_NumDescrMarks = new HTuple(hv_X.TupleLength());
			for (hv_Index = 1; hv_Index.Continue(hv_Number, 1); hv_Index = hv_Index.TupleAdd(1))
			{
				ho_ObjectSelected.Dispose();
				HOperatorSet.SelectObj(ho_RegionDifference, out ho_ObjectSelected, hv_Index);
				ho_ConnectedMarks.Dispose();
				HOperatorSet.Connection(ho_ObjectSelected, out ho_ConnectedMarks);
				HOperatorSet.CountObj(ho_ConnectedMarks, out hv_NumberMarks);
				HOperatorSet.Eccentricity(ho_ConnectedMarks, out hv_Anisometry, out hv_Bulkiness,
					out hv_StructureFactor);
				HOperatorSet.AreaCenter(ho_ConnectedMarks, out hv_AreaMarks, out hv_Row, out hv_Column);
				ho_ObjectSelectedCaltab.Dispose();
				HOperatorSet.SelectObj(ho_RegionIntersection, out ho_ObjectSelectedCaltab,
					hv_Index);
				if ((int)((new HTuple((new HTuple((new HTuple(hv_NumberMarks.TupleGreaterEqual(
					10))).TupleAnd(new HTuple(hv_NumberMarks.TupleLess(hv_NumDescrMarks + 20))))).TupleAnd(
					new HTuple(((((hv_Anisometry.TupleSort())).TupleSelect((new HTuple(hv_Anisometry.TupleLength()
					)) / 2))).TupleLess(2))))).TupleAnd(new HTuple((new HTuple(hv_AreaMarks.TupleMean()
					)).TupleGreater(20)))) != 0)
				{
					OTemp[SP_O] = ho_CaltabCandidates.CopyObj(1, -1);
					SP_O++;
					ho_CaltabCandidates.Dispose();
					HOperatorSet.ConcatObj(OTemp[SP_O - 1], ho_ObjectSelectedCaltab, out ho_CaltabCandidates
						);
					OTemp[SP_O - 1].Dispose();
					SP_O = 0;
				}
			}
			ho_RegionFillUpCand.Dispose();
			HOperatorSet.FillUp(ho_CaltabCandidates, out ho_RegionFillUpCand);
			HOperatorSet.Rectangularity(ho_RegionFillUpCand, out hv_Rectangularity);
			if ((int)(new HTuple((new HTuple(hv_Rectangularity.TupleLength())).TupleEqual(
				0))) != 0)
			{
				ho_ImageMean.Dispose();
				ho_RegionDynThresh.Dispose();
				ho_RegionBorder.Dispose();
				ho_RegionOpening1.Dispose();
				ho_ConnectedRegions1.Dispose();
				ho_SelectedRegions4.Dispose();
				ho_SelectedRegions5.Dispose();
				ho_RegionBorder2.Dispose();
				ho_RegionTrans.Dispose();
				ho_RegionErosion.Dispose();
				ho_RegionBorder1.Dispose();
				ho_RegionDilation2.Dispose();
				ho_RegionDifference1.Dispose();
				ho_RegionOpening.Dispose();
				ho_ConnectedRegions.Dispose();
				ho_SelectedRegions2.Dispose();
				ho_SelectedRegions.Dispose();
				ho_RegionFillUp.Dispose();
				ho_SelectedRegions1.Dispose();
				ho_RegionIntersection.Dispose();
				ho_RegionFillUp1.Dispose();
				ho_RegionDifference.Dispose();
				ho_CaltabCandidates.Dispose();
				ho_ObjectSelected.Dispose();
				ho_ConnectedMarks.Dispose();
				ho_ObjectSelectedCaltab.Dispose();
				ho_RegionFillUpCand.Dispose();
				ho_MarksCand.Dispose();
				ho_RegionDilation1.Dispose();
				ho_ImageReduced.Dispose();
				ho_DefaultEdges.Dispose();
				ho_UnionContours.Dispose();
				ho_SelectedXLD.Dispose();
				ho_SelectedXLD1.Dispose();

				return;
			}
			hv_SortedIndex = hv_Rectangularity.TupleSortIndex();
			hv_IndexBest = (((hv_SortedIndex.TupleInverse())).TupleSelect(0)) + 1;
			ho_Caltab.Dispose();
			HOperatorSet.SelectObj(ho_RegionFillUpCand, out ho_Caltab, hv_IndexBest);
			ho_RegionFillUp.Dispose();
			HOperatorSet.FillUp(ho_Caltab, out ho_RegionFillUp);
			ho_MarksCand.Dispose();
			HOperatorSet.Difference(ho_RegionFillUp, ho_RegionDynThresh, out ho_MarksCand
				);
			ho_RegionBorder.Dispose();
			HOperatorSet.Boundary(ho_MarksCand, out ho_RegionBorder, "inner");
			ho_RegionDilation1.Dispose();
			HOperatorSet.DilationCircle(ho_RegionBorder, out ho_RegionDilation1, 9.5);
			ho_ImageReduced.Dispose();
			HOperatorSet.ReduceDomain(ho_Image, ho_RegionDilation1, out ho_ImageReduced);
			hv_MinContrast = 10;
			ho_DefaultEdges.Dispose();
			HOperatorSet.EdgesSubPix(ho_ImageReduced, out ho_DefaultEdges, "canny", 2, hv_MinContrast / 2,
				hv_MinContrast);
			HOperatorSet.CountObj(ho_DefaultEdges, out hv_NumberCand);
			if ((int)(new HTuple(hv_NumberCand.TupleLess(10))) != 0)
			{
				ho_ImageMean.Dispose();
				ho_RegionDynThresh.Dispose();
				ho_RegionBorder.Dispose();
				ho_RegionOpening1.Dispose();
				ho_ConnectedRegions1.Dispose();
				ho_SelectedRegions4.Dispose();
				ho_SelectedRegions5.Dispose();
				ho_RegionBorder2.Dispose();
				ho_RegionTrans.Dispose();
				ho_RegionErosion.Dispose();
				ho_RegionBorder1.Dispose();
				ho_RegionDilation2.Dispose();
				ho_RegionDifference1.Dispose();
				ho_RegionOpening.Dispose();
				ho_ConnectedRegions.Dispose();
				ho_SelectedRegions2.Dispose();
				ho_SelectedRegions.Dispose();
				ho_RegionFillUp.Dispose();
				ho_SelectedRegions1.Dispose();
				ho_RegionIntersection.Dispose();
				ho_RegionFillUp1.Dispose();
				ho_RegionDifference.Dispose();
				ho_CaltabCandidates.Dispose();
				ho_ObjectSelected.Dispose();
				ho_ConnectedMarks.Dispose();
				ho_ObjectSelectedCaltab.Dispose();
				ho_RegionFillUpCand.Dispose();
				ho_MarksCand.Dispose();
				ho_RegionDilation1.Dispose();
				ho_ImageReduced.Dispose();
				ho_DefaultEdges.Dispose();
				ho_UnionContours.Dispose();
				ho_SelectedXLD.Dispose();
				ho_SelectedXLD1.Dispose();

				return;
			}
			ho_UnionContours.Dispose();
			HOperatorSet.UnionCocircularContoursXld(ho_DefaultEdges, out ho_UnionContours,
				0.5, 0.1, 0.2, 30, 10, 10, "true", 1);
			ho_SelectedXLD.Dispose();
			HOperatorSet.SelectShapeXld(ho_UnionContours, out ho_SelectedXLD, "area", "and",
				30, 10000);
			ho_SelectedXLD1.Dispose();
			HOperatorSet.SelectShapeXld(ho_SelectedXLD, out ho_SelectedXLD1, "circularity",
				"and", 0.4, 1);
			ho_MarksCand.Dispose();
			HOperatorSet.SelectShapeXld(ho_SelectedXLD1, out ho_MarksCand, "compactness",
				"and", 1, 1.5);
			HOperatorSet.AreaCenterXld(ho_MarksCand, out hv_Area, out hv_Dummy, out hv_Dummy,
				out hv_DummyS);
			HOperatorSet.CountObj(ho_MarksCand, out hv_Number);
			if ((int)(new HTuple(hv_Number.TupleLess(4))) != 0)
			{
				ho_ImageMean.Dispose();
				ho_RegionDynThresh.Dispose();
				ho_RegionBorder.Dispose();
				ho_RegionOpening1.Dispose();
				ho_ConnectedRegions1.Dispose();
				ho_SelectedRegions4.Dispose();
				ho_SelectedRegions5.Dispose();
				ho_RegionBorder2.Dispose();
				ho_RegionTrans.Dispose();
				ho_RegionErosion.Dispose();
				ho_RegionBorder1.Dispose();
				ho_RegionDilation2.Dispose();
				ho_RegionDifference1.Dispose();
				ho_RegionOpening.Dispose();
				ho_ConnectedRegions.Dispose();
				ho_SelectedRegions2.Dispose();
				ho_SelectedRegions.Dispose();
				ho_RegionFillUp.Dispose();
				ho_SelectedRegions1.Dispose();
				ho_RegionIntersection.Dispose();
				ho_RegionFillUp1.Dispose();
				ho_RegionDifference.Dispose();
				ho_CaltabCandidates.Dispose();
				ho_ObjectSelected.Dispose();
				ho_ConnectedMarks.Dispose();
				ho_ObjectSelectedCaltab.Dispose();
				ho_RegionFillUpCand.Dispose();
				ho_MarksCand.Dispose();
				ho_RegionDilation1.Dispose();
				ho_ImageReduced.Dispose();
				ho_DefaultEdges.Dispose();
				ho_UnionContours.Dispose();
				ho_SelectedXLD.Dispose();
				ho_SelectedXLD1.Dispose();

				return;
			}
			hv_AreaMedian = ((hv_Area.TupleSort())).TupleSelect(hv_Number / 2);
			ho_Marks.Dispose();
			HOperatorSet.SelectShapeXld(ho_MarksCand, out ho_Marks, "area", "and", hv_AreaMedian - (hv_AreaMedian * 0.5),
				hv_AreaMedian + (hv_AreaMedian * 0.5));
			ho_ImageMean.Dispose();
			ho_RegionDynThresh.Dispose();
			ho_RegionBorder.Dispose();
			ho_RegionOpening1.Dispose();
			ho_ConnectedRegions1.Dispose();
			ho_SelectedRegions4.Dispose();
			ho_SelectedRegions5.Dispose();
			ho_RegionBorder2.Dispose();
			ho_RegionTrans.Dispose();
			ho_RegionErosion.Dispose();
			ho_RegionBorder1.Dispose();
			ho_RegionDilation2.Dispose();
			ho_RegionDifference1.Dispose();
			ho_RegionOpening.Dispose();
			ho_ConnectedRegions.Dispose();
			ho_SelectedRegions2.Dispose();
			ho_SelectedRegions.Dispose();
			ho_RegionFillUp.Dispose();
			ho_SelectedRegions1.Dispose();
			ho_RegionIntersection.Dispose();
			ho_RegionFillUp1.Dispose();
			ho_RegionDifference.Dispose();
			ho_CaltabCandidates.Dispose();
			ho_ObjectSelected.Dispose();
			ho_ConnectedMarks.Dispose();
			ho_ObjectSelectedCaltab.Dispose();
			ho_RegionFillUpCand.Dispose();
			ho_MarksCand.Dispose();
			ho_RegionDilation1.Dispose();
			ho_ImageReduced.Dispose();
			ho_DefaultEdges.Dispose();
			ho_UnionContours.Dispose();
			ho_SelectedXLD.Dispose();
			ho_SelectedXLD1.Dispose();

			return;
		}



		/// <summary>
		/// Determines whether the calibration image is overexposed
		/// </summary>
		public void eval_caltab_overexposure(HObject ho_Image,
											  HObject ho_Caltab,
											  out HTuple hv_OverexposureScore)
		{

			// Local iconic variables 

			HObject ho_ImageReduced, ho_Region;


			// Local control variables 

			HTuple hv_AreaCaltab, hv_Row, hv_Column, hv_AreaOverExp;
			HTuple hv_Thresh, hv_Ratio;

			// Initialize local and output iconic variables 
			HOperatorSet.GenEmptyObj(out ho_ImageReduced);
			HOperatorSet.GenEmptyObj(out ho_Region);

			//returns a measure of the amount of saturation of the plate
			hv_OverexposureScore = 0.0;
			HOperatorSet.AreaCenter(ho_Caltab, out hv_AreaCaltab, out hv_Row, out hv_Column);
			if ((int)((new HTuple(hv_AreaCaltab.TupleEqual(0))).TupleOr(new HTuple(hv_AreaCaltab.TupleEqual(
				new HTuple())))) != 0)
			{
				ho_ImageReduced.Dispose();
				ho_Region.Dispose();

				return;
			}
			ho_ImageReduced.Dispose();
			HOperatorSet.ReduceDomain(ho_Image, ho_Caltab, out ho_ImageReduced);
			ho_Region.Dispose();
			HOperatorSet.Threshold(ho_ImageReduced, out ho_Region, 255, 255);
			HOperatorSet.AreaCenter(ho_Region, out hv_AreaOverExp, out hv_Row, out hv_Column);
			hv_Thresh = 0.15;
			hv_Ratio = (hv_AreaOverExp.TupleReal()) / hv_AreaCaltab;
			if ((int)(new HTuple(hv_Ratio.TupleLess(hv_Thresh))) != 0)
			{
				hv_OverexposureScore = (((new HTuple(1.0)).TupleConcat(1 - (hv_Ratio / hv_Thresh)))).TupleMin()
					;
			}
			ho_ImageReduced.Dispose();
			ho_Region.Dispose();

			return;
		}


		/// <summary>
		/// Evaluates the gray value contrast between the marks and the calibration 
		/// plate and the homogeneity of the used illumination.
		/// </summary>
		public void eval_caltab_contrast_homogeneity(HObject ho_Image,
													  HObject ho_Marks,
													  out HTuple hv_Contrast,
													  out HTuple hv_ContrastScore,
													  out HTuple hv_HomogeneityScore)
		{

			// Local iconic variables 

			HObject ho_Region, ho_RegionDilation;


			// Local control variables 

			HTuple hv_Number, hv_Min, hv_Max, hv_Range;
			HTuple hv_MinContrast, hv_MaxContrast, hv_DeviationMax;

			// Initialize local and output iconic variables 
			HOperatorSet.GenEmptyObj(out ho_Region);
			HOperatorSet.GenEmptyObj(out ho_RegionDilation);

			hv_ContrastScore = 0.0;
			hv_Contrast = 0.0;
			hv_HomogeneityScore = 0.0;
			HOperatorSet.CountObj(ho_Marks, out hv_Number);
			if ((int)(new HTuple(hv_Number.TupleLess(4))) != 0)
			{
				ho_Region.Dispose();
				ho_RegionDilation.Dispose();

				return;
			}
			ho_Region.Dispose();
			HOperatorSet.GenRegionContourXld(ho_Marks, out ho_Region, "margin");
			ho_RegionDilation.Dispose();
			HOperatorSet.DilationCircle(ho_Region, out ho_RegionDilation, 5.5);
			HOperatorSet.MinMaxGray(ho_RegionDilation, ho_Image, 3, out hv_Min, out hv_Max,
				out hv_Range);
			//Calculate contrast score
			hv_Contrast = hv_Range.TupleMean();
			hv_MinContrast = 70;
			hv_MaxContrast = 160;
			if ((int)(new HTuple(hv_Contrast.TupleGreater(hv_MinContrast))) != 0)
			{
				hv_ContrastScore = (hv_Contrast - hv_MinContrast) / (hv_MaxContrast - hv_MinContrast);
				hv_ContrastScore = ((hv_ContrastScore.TupleConcat(1.0))).TupleMin();
			}
			//Now for the homogeneity score
			HOperatorSet.TupleDeviation(hv_Max, out hv_DeviationMax);
			hv_HomogeneityScore = 1.1 - (hv_DeviationMax / 40.0);
			hv_HomogeneityScore = ((((((hv_HomogeneityScore.TupleConcat(1.0))).TupleMin()
				)).TupleConcat(0.0))).TupleMax();
			ho_Region.Dispose();
			ho_RegionDilation.Dispose();

			return;
		}

		/// <summary>
		/// Evaluates the area covered by the calibration plate in the calibration
		/// image.
		/// </summary>
		public void eval_caltab_size(HObject ho_Image,
									  HObject ho_Caltab,
									  HObject ho_Marks,
									  out HTuple hv_SizeScore)
		{

			// Local iconic variables 

			HObject ho_Region = null, ho_RegionUnion = null;


			// Local control variables 

			HTuple hv_Pointer, hv_Type, hv_Width, hv_Height;
			HTuple hv_Number, hv_Row1 = new HTuple(), hv_Column1 = new HTuple();
			HTuple hv_Phi1 = new HTuple(), hv_Length1 = new HTuple(), hv_Length2 = new HTuple();
			HTuple hv_Area = new HTuple(), hv_Row = new HTuple(), hv_Column = new HTuple();
			HTuple hv_MinRatio, hv_MaxRatio, hv_Ratio;

			// Initialize local and output iconic variables 
			HOperatorSet.GenEmptyObj(out ho_Region);
			HOperatorSet.GenEmptyObj(out ho_RegionUnion);

			hv_SizeScore = 0.0;
			HOperatorSet.GetImagePointer1(ho_Image, out hv_Pointer, out hv_Type, out hv_Width,
				out hv_Height);
			HOperatorSet.CountObj(ho_Marks, out hv_Number);
			if ((int)(new HTuple(hv_Number.TupleGreaterEqual(4))) != 0)
			{
				//Best approach: Use the surrounding box of the marks as reference size
				ho_Region.Dispose();
				HOperatorSet.GenRegionContourXld(ho_Marks, out ho_Region, "filled");
				ho_RegionUnion.Dispose();
				HOperatorSet.Union1(ho_Region, out ho_RegionUnion);
				HOperatorSet.SmallestRectangle2(ho_RegionUnion, out hv_Row1, out hv_Column1,
					out hv_Phi1, out hv_Length1, out hv_Length2);
				hv_Area = (hv_Length2 * hv_Length1) * 4;
			}
			else
			{
				//If no marks could be found: use the caltab as reference size
				HOperatorSet.AreaCenter(ho_Caltab, out hv_Area, out hv_Row, out hv_Column);
				if ((int)((new HTuple(hv_Area.TupleEqual(0))).TupleOr(new HTuple(hv_Area.TupleEqual(
					new HTuple())))) != 0)
				{
					ho_Region.Dispose();
					ho_RegionUnion.Dispose();

					return;
				}
			}
			hv_MinRatio = 0.015;
			hv_MaxRatio = 0.075;
			hv_Ratio = (hv_Area.TupleReal()) / (hv_Width * hv_Height);
			if ((int)(new HTuple(hv_Ratio.TupleGreater(hv_MinRatio))) != 0)
			{
				hv_SizeScore = (hv_Ratio - hv_MinRatio) / (hv_MaxRatio - hv_MinRatio);
				hv_SizeScore = (((new HTuple(1.0)).TupleConcat(hv_SizeScore))).TupleMin();
			}
			ho_Region.Dispose();
			ho_RegionUnion.Dispose();

			return;
		}

		/// <summary>
		/// Display the axes of a 3d coordinate system.
		/// </summary>
		private void disp_3d_coord_system(HTuple hv_WindowHandle,
										  HTuple hv_CamParam,
										  HTuple hv_Pose,
										  HTuple hv_CoordAxesLength)
		{

			// Local iconic variables 

			HObject ho_ContX, ho_ContY, ho_ContZ;


			// Local control variables 

			HTuple hv_TransWorld2Cam, hv_OrigCamX, hv_OrigCamY;
			HTuple hv_OrigCamZ, hv_Row0, hv_Column0, hv_X, hv_Y, hv_Z;
			HTuple hv_RowAxX, hv_ColumnAxX, hv_RowAxY, hv_ColumnAxY;
			HTuple hv_RowAxZ, hv_ColumnAxZ;

			// Initialize local and output iconic variables 
			HOperatorSet.GenEmptyObj(out ho_ContX);
			HOperatorSet.GenEmptyObj(out ho_ContY);
			HOperatorSet.GenEmptyObj(out ho_ContZ);

			if ((int)(new HTuple((new HTuple(hv_Pose.TupleLength())).TupleNotEqual(7))) != 0)
			{
				ho_ContX.Dispose();
				ho_ContY.Dispose();
				ho_ContZ.Dispose();

				return;
			}
			if ((int)(new HTuple(((hv_Pose.TupleSelect(5))).TupleEqual(0.0))) != 0)
			{
				ho_ContX.Dispose();
				ho_ContY.Dispose();
				ho_ContZ.Dispose();

				return;
			}
			HOperatorSet.PoseToHomMat3d(hv_Pose, out hv_TransWorld2Cam);
			//Project the world origin into the image
			HOperatorSet.AffineTransPoint3d(hv_TransWorld2Cam, 0, 0, 0, out hv_OrigCamX,
				out hv_OrigCamY, out hv_OrigCamZ);
			HOperatorSet.Project3dPoint(hv_OrigCamX, hv_OrigCamY, hv_OrigCamZ, hv_CamParam,
				out hv_Row0, out hv_Column0);
			//Project the coordinate axes into the image
			HOperatorSet.AffineTransPoint3d(hv_TransWorld2Cam, hv_CoordAxesLength, 0, 0,
				out hv_X, out hv_Y, out hv_Z);
			HOperatorSet.Project3dPoint(hv_X, hv_Y, hv_Z, hv_CamParam, out hv_RowAxX, out hv_ColumnAxX);
			HOperatorSet.AffineTransPoint3d(hv_TransWorld2Cam, 0, hv_CoordAxesLength, 0,
				out hv_X, out hv_Y, out hv_Z);
			HOperatorSet.Project3dPoint(hv_X, hv_Y, hv_Z, hv_CamParam, out hv_RowAxY, out hv_ColumnAxY);
			HOperatorSet.AffineTransPoint3d(hv_TransWorld2Cam, 0, 0, hv_CoordAxesLength,
				out hv_X, out hv_Y, out hv_Z);
			HOperatorSet.Project3dPoint(hv_X, hv_Y, hv_Z, hv_CamParam, out hv_RowAxZ, out hv_ColumnAxZ);
			ho_ContX.Dispose();
			gen_arrow_cont(out ho_ContX, hv_Row0, hv_Column0, hv_RowAxX, hv_ColumnAxX);
			ho_ContY.Dispose();
			gen_arrow_cont(out ho_ContY, hv_Row0, hv_Column0, hv_RowAxY, hv_ColumnAxY);
			ho_ContZ.Dispose();
			gen_arrow_cont(out ho_ContZ, hv_Row0, hv_Column0, hv_RowAxZ, hv_ColumnAxZ);
			if (HDevWindowStack.IsOpen())
			{
				//dev_display (ContX)
			}
			if (HDevWindowStack.IsOpen())
			{
				//dev_display (ContY)
			}
			if (HDevWindowStack.IsOpen())
			{
				//dev_display (ContZ)
			}
			HOperatorSet.DispObj(ho_ContX, hv_WindowHandle);
			HOperatorSet.DispObj(ho_ContY, hv_WindowHandle);
			HOperatorSet.DispObj(ho_ContZ, hv_WindowHandle);
			HOperatorSet.SetTposition(hv_WindowHandle, hv_RowAxX + 3, hv_ColumnAxX + 3);
			HOperatorSet.WriteString(hv_WindowHandle, "X");
			HOperatorSet.SetTposition(hv_WindowHandle, hv_RowAxY + 3, hv_ColumnAxY + 3);
			HOperatorSet.WriteString(hv_WindowHandle, "Y");
			HOperatorSet.SetTposition(hv_WindowHandle, hv_RowAxZ + 3, hv_ColumnAxZ + 3);
			HOperatorSet.WriteString(hv_WindowHandle, "Z");
			ho_ContX.Dispose();
			ho_ContY.Dispose();
			ho_ContZ.Dispose();

			return;
		}

		/// <summary>
		/// Generate a contour in form of an arrow.
		/// </summary>
		private void gen_arrow_cont(out HObject ho_Arrow,
									HTuple hv_Row1,
									HTuple hv_Column1,
									HTuple hv_Row2,
									HTuple hv_Column2)
		{

			// Local iconic variables 

			HObject ho_Cross1, ho_Cross2, ho_CrossP1, ho_CrossP2;


			// Local control variables 

			HTuple hv_Length, hv_Angle, hv_MinArrowLength;
			HTuple hv_DRow, hv_DCol, hv_ArrowLength, hv_Phi, hv_P1R;
			HTuple hv_P1C, hv_P2R, hv_P2C;

			// Initialize local and output iconic variables 
			HOperatorSet.GenEmptyObj(out ho_Arrow);
			HOperatorSet.GenEmptyObj(out ho_Cross1);
			HOperatorSet.GenEmptyObj(out ho_Cross2);
			HOperatorSet.GenEmptyObj(out ho_CrossP1);
			HOperatorSet.GenEmptyObj(out ho_CrossP2);

			//Generate a contour in form of a arrow
			hv_Length = 7;
			hv_Angle = 40;
			hv_MinArrowLength = 2;
			hv_DRow = hv_Row2 - hv_Row1;
			hv_DCol = hv_Column2 - hv_Column1;
			hv_ArrowLength = (((hv_DRow * hv_DRow) + (hv_DCol * hv_DCol))).TupleSqrt();
			if ((int)(new HTuple(hv_ArrowLength.TupleLess(hv_MinArrowLength))) != 0)
			{
				hv_Length = 0;
			}
			HOperatorSet.TupleAtan2(hv_DRow, -hv_DCol, out hv_Phi);
			hv_P1R = hv_Row2 - (hv_Length * (((hv_Phi - (hv_Angle.TupleRad()))).TupleSin()));
			hv_P1C = hv_Column2 + (hv_Length * (((hv_Phi - (hv_Angle.TupleRad()))).TupleCos()));
			hv_P2R = hv_Row2 - (hv_Length * (((hv_Phi + (hv_Angle.TupleRad()))).TupleSin()));
			hv_P2C = hv_Column2 + (hv_Length * (((hv_Phi + (hv_Angle.TupleRad()))).TupleCos()));
			ho_Cross1.Dispose();
			HOperatorSet.GenCrossContourXld(out ho_Cross1, hv_Row1, hv_Column1, 6, 0.785398);
			ho_Cross2.Dispose();
			HOperatorSet.GenCrossContourXld(out ho_Cross2, hv_Row2, hv_Column2, 6, 0.785398);
			ho_CrossP1.Dispose();
			HOperatorSet.GenCrossContourXld(out ho_CrossP1, hv_P1R, hv_P1C, 6, 0.785398);
			ho_CrossP2.Dispose();
			HOperatorSet.GenCrossContourXld(out ho_CrossP2, hv_P2R, hv_P2C, 6, 0.785398);
			ho_Arrow.Dispose();
			HOperatorSet.GenContourPolygonXld(out ho_Arrow, ((((((hv_Row1.TupleConcat(hv_Row2))).TupleConcat(
				hv_P1R))).TupleConcat(hv_Row2))).TupleConcat(hv_P2R), ((((((hv_Column1.TupleConcat(
				hv_Column2))).TupleConcat(hv_P1C))).TupleConcat(hv_Column2))).TupleConcat(
				hv_P2C));
			ho_Cross1.Dispose();
			ho_Cross2.Dispose();
			ho_CrossP1.Dispose();
			ho_CrossP2.Dispose();

			return;
		}

		private void tuple_equal_greater(HTuple hv_Tuple,
										 HTuple hv_Threshold,
										 out HTuple hv_Selected,
										 out HTuple hv_Indices)
		{

			// Local control variables 

			HTuple hv_Sgn;

			// Initialize local and output iconic variables 

			hv_Selected = new HTuple();
			HOperatorSet.TupleSgn(hv_Tuple - hv_Threshold, out hv_Sgn);
			HOperatorSet.TupleFind(hv_Sgn, 1, out hv_Indices);
			if ((int)((new HTuple((new HTuple(hv_Indices.TupleLength())).TupleGreater(1))).TupleOr(
				new HTuple(((hv_Indices.TupleSelect(0))).TupleNotEqual(-1)))) != 0)
			{
				HOperatorSet.TupleSelect(hv_Tuple, hv_Indices, out hv_Selected);
			}

			return;
		}

		private void gen_fuzzy_weight_funct(HTuple hv_NPoints,
											HTuple hv_Min,
											HTuple hv_Max,
											HTuple hv_LowPass,
											HTuple hv_HighPass,
											out HTuple hv_FuzzyFunct)
		{

			// Local control variables 

			HTuple hv_Ones, hv_Index, hv_X, hv_Y, hv_Dummy;
			HTuple hv_IndicesTrans, hv_IndicesHigh, hv_i, hv_NTransPoints;

			// Initialize local and output iconic variables 

			//generates a function which is 0.0 for values lower than LowPass, 1.0 for
			//values over HighPass, and grows linearly for values in between the two
			HOperatorSet.TupleGenConst(hv_NPoints, 1, out hv_Ones);
			hv_Index = ((hv_Ones.TupleCumul()) - 1) / ((new HTuple(hv_Ones.TupleLength())).TupleReal()
				);
			hv_X = (hv_Index * (hv_Max - hv_Min)) + hv_Min;
			HOperatorSet.TupleGenConst(new HTuple(hv_X.TupleLength()), 0.0, out hv_Y);
			tuple_equal_greater(hv_X, hv_LowPass, out hv_Dummy, out hv_IndicesTrans);
			tuple_equal_greater(hv_X, hv_HighPass, out hv_Dummy, out hv_IndicesHigh);
			//ramp from LowPass (0.0) to Highpass (1.0)
			hv_i = 0;
			while ((int)(new HTuple(((hv_IndicesTrans.TupleSelect(hv_i))).TupleLess(hv_IndicesHigh.TupleSelect(
				0)))) != 0)
			{
				hv_i = hv_i + 1;
			}
			hv_NTransPoints = hv_i.Clone();
			for (hv_i = 0; hv_i.Continue(hv_NTransPoints - 1, 1); hv_i = hv_i.TupleAdd(1))
			{
				hv_Y[hv_IndicesTrans.TupleSelect(hv_i)] = (hv_i.TupleReal()) / hv_NTransPoints;
			}
			for (hv_i = hv_IndicesTrans.TupleSelect(hv_NTransPoints); hv_i.Continue((new HTuple(hv_Y.TupleLength()
				)) - 1, 1); hv_i = hv_i.TupleAdd(1))
			{
				hv_Y[hv_i] = 1.0;
			}
			HOperatorSet.CreateFunct1dPairs(hv_X, hv_Y, out hv_FuzzyFunct);

			return;
		}


		/// <summary>
		/// Measures the tilt that is used for the plates in the set
		/// of calibration images. The more tilted plates are used
		/// in the image set, the better you can correct the radial 
		/// distortion of the lense by performing the calibration.
		/// </summary>
		public void eval_caltab_tilt(HTuple hv_FinalPoses,
									  out HTuple hv_TiltScore)
		{

			// Local control variables 

			HTuple hv_NImages, hv_Ones, hv_Index, hv_Slant;
			HTuple hv_Pan, hv_FuzzyFunct, hv_SlantWeight, hv_PanWeight;
			HTuple hv_TmpPan, hv_TmpSlant;

			// Initialize local and output iconic variables 

			hv_NImages = (new HTuple(hv_FinalPoses.TupleLength())) / 7;
			HOperatorSet.TupleGenConst(hv_NImages, 1, out hv_Ones);
			hv_Index = (hv_Ones.TupleCumul()) - 1;
			HOperatorSet.TupleSelect(hv_FinalPoses, (7 * hv_Index) + 3, out hv_Slant);
			HOperatorSet.TupleSelect(hv_FinalPoses, (7 * hv_Index) + 4, out hv_Pan);
			for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_Slant.TupleLength())) - 1); hv_Index = (int)hv_Index + 1)
			{
				if ((int)(new HTuple(((hv_Slant.TupleSelect(hv_Index))).TupleGreater(180))) != 0)
				{
					hv_Slant[hv_Index] = 360 - (hv_Slant.TupleSelect(hv_Index));
				}
			}
			for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_Pan.TupleLength())) - 1); hv_Index = (int)hv_Index + 1)
			{
				if ((int)(new HTuple(((hv_Pan.TupleSelect(hv_Index))).TupleGreater(180))) != 0)
				{
					hv_Pan[hv_Index] = 360 - (hv_Pan.TupleSelect(hv_Index));
				}
			}
			hv_Pan = hv_Pan.TupleRad();
			hv_Slant = hv_Slant.TupleRad();
			//function acting as a fuzzy weighting
			gen_fuzzy_weight_funct(256, (new HTuple(0.0)).TupleRad(), (new HTuple(90.0)).TupleRad()
				, (new HTuple(15.0)).TupleRad(), (new HTuple(40.0)).TupleRad(), out hv_FuzzyFunct);
			HOperatorSet.GetYValueFunct1d(hv_FuzzyFunct, hv_Slant, "constant", out hv_SlantWeight);
			HOperatorSet.GetYValueFunct1d(hv_FuzzyFunct, hv_Pan, "constant", out hv_PanWeight);
			//Calculate score value
			hv_TmpPan = (hv_PanWeight.TupleSum()) / 6;
			hv_TmpPan = ((hv_TmpPan.TupleConcat(0.5))).TupleMin();
			hv_TmpSlant = (hv_SlantWeight.TupleSum()) / 6;
			hv_TmpSlant = ((hv_TmpSlant.TupleConcat(0.5))).TupleMin();
			hv_TiltScore = hv_TmpSlant + hv_TmpPan;

			return;
		}


		/// <summary>
		/// Evaluates the distribution of the marks and hence the plates
		/// used for the calibration images. Precise measurements can only be
		/// achieved if the field view of the camera is covered well by the
		/// calibration plate in the images.
		/// </summary>
		public void eval_marks_distribution(HTuple hv_NRCoord,
											 HTuple hv_NCCoord,
											 HTuple hv_Width,
											 HTuple hv_Height,
											 out HTuple hv_MarksDistributionScore)
		{

			// Local iconic variables 

			HObject ho_Region, ho_DistanceImage, ho_Mask;


			// Local control variables 

			HTuple hv_Border, hv_Min, hv_Max, hv_Range;
			HTuple hv_ImageDiagonal, hv_MinThresh, hv_MaxThresh, hv_Ratio;
			HTuple hv_Tmp1, hv_Tmp2;

			// Initialize local and output iconic variables 
			HOperatorSet.GenEmptyObj(out ho_Region);
			HOperatorSet.GenEmptyObj(out ho_DistanceImage);
			HOperatorSet.GenEmptyObj(out ho_Mask);

			//Determine the distances between the marks centers
			ho_Region.Dispose();
			HOperatorSet.GenRegionPoints(out ho_Region, hv_NRCoord, hv_NCCoord);
			ho_DistanceImage.Dispose();
			HOperatorSet.DistanceTransform(ho_Region, out ho_DistanceImage, "octagonal",
				"false", hv_Width, hv_Height);
			//A clipping is needed because the marks cannot come close to the border
			hv_Border = (((hv_Width.TupleConcat(hv_Height))).TupleMax()) / 15;
			ho_Mask.Dispose();
			HOperatorSet.GenRectangle1(out ho_Mask, hv_Border, hv_Border, (hv_Height - 1) - hv_Border,
				(hv_Width - 1) - hv_Border);
			HOperatorSet.MinMaxGray(ho_Mask, ho_DistanceImage, 0, out hv_Min, out hv_Max,
				out hv_Range);
			HOperatorSet.DistancePp(0, 0, hv_Height - 1, hv_Width - 1, out hv_ImageDiagonal);
			hv_MinThresh = 0.3;
			hv_MaxThresh = 0.85;
			hv_Ratio = (hv_Max / hv_ImageDiagonal) * 2.5;
			hv_Tmp1 = 1 - hv_Ratio;
			hv_Tmp2 = (hv_Tmp1 - hv_MinThresh) / (hv_MaxThresh - hv_MinThresh);
			hv_MarksDistributionScore = ((((((hv_Tmp2.TupleConcat(1.0))).TupleMin())).TupleConcat(
				0.0))).TupleMax();
			ho_Region.Dispose();
			ho_DistanceImage.Dispose();
			ho_Mask.Dispose();

			return;
		}

		/// <summary>
		/// Auxiliary method for display purposes. Returns the coordinate system
		/// described by the parameters <c>hv_CamParam</c> and <c>hv_Pose</c>
		/// as an iconic object.
		/// </summary>
		public void get_3d_coord_system(HObject ho_ImageReference,
										 out HObject ho_CoordSystemRegion,
										 HTuple hv_CamParam,
										 HTuple hv_Pose,
										 HTuple hv_CoordAxesLength)
		{


			// Local iconic variables 

			HObject ho_CoordSystemImage;


			// Local control variables 

			HTuple hv_Pointer, hv_Type, hv_Width, hv_Height;
			HTuple hv_OldBG, hv_WindowHandle;

			// Initialize local and output iconic variables 
			HOperatorSet.GenEmptyObj(out ho_CoordSystemRegion);
			HOperatorSet.GenEmptyObj(out ho_CoordSystemImage);

			HOperatorSet.GetImagePointer1(ho_ImageReference, out hv_Pointer, out hv_Type,
				out hv_Width, out hv_Height);
			HOperatorSet.GetWindowAttr("background_color", out hv_OldBG);
			HOperatorSet.SetWindowAttr("background_color", "black");
			HOperatorSet.OpenWindow(0, 0, hv_Width, hv_Height, 0, "buffer", "", out hv_WindowHandle);
			HOperatorSet.SetWindowAttr("background_color", hv_OldBG);
			HOperatorSet.SetColor(hv_WindowHandle, "white");
			HOperatorSet.SetPart(hv_WindowHandle, 0, 0, hv_Height - 1, hv_Width - 1);
			disp_3d_coord_system(hv_WindowHandle, hv_CamParam, hv_Pose, hv_CoordAxesLength);
			ho_CoordSystemImage.Dispose();
			HOperatorSet.DumpWindowImage(out ho_CoordSystemImage, hv_WindowHandle);
			HOperatorSet.CloseWindow(hv_WindowHandle);
			ho_CoordSystemRegion.Dispose();
			HOperatorSet.Threshold(ho_CoordSystemImage, out ho_CoordSystemRegion, 255, 255);
			ho_CoordSystemImage.Dispose();

			return;
		}

	}//end of class
}
